/* 
泛型:  不确定的类型
    定义函数/类/接口时, 不确定的类型, 使用时才指定具体类型
    指在定义函数、接口或类的时候，不预先指定具体的类型，而在使用的时候再指定具体类型的一种特性。

泛泛而谈 => 大概的/不确定的/不具体

需求:
  创建一个函数, 实现功能: 根据指定的数量 count 和数据 value , 
  创建一个包含 count 个 value 的数组
*/

(() => {
  /* 
  1. 定义泛型: 定义函数的函数名右侧  <泛型名称>   <T>
  2. 使用泛型: 在形参/返回值/函数体中使用
  3. 指定具体类型: 在调用函数时, 函数名的右侧 <具体类型>
  */
  function getArray<T>(count: number, value: T): T[] {
    const arr: T[] = []

    for (let index = 0; index < count; index++) {
      arr.push(value)
    }

    return arr
  }

  const arr1 = getArray<string>(4, 'abcde')
  console.log(arr1[1].length)
  const arr2 = getArray<number>(5, 123.123)
  console.log(arr2[2].toFixed())

  // 使用泛型能极大的增强提示(正确/错误)

})();


(() => {
  // 定义函数时, 不确定参数的类型, 只有指定any了
  // 问题: 后面使用时就不能知道具体的数据类型
  // 解决: 使用泛型技术来解决
  function getArray(count: number, value: any): any[] {
    const arr: any[] = []

    for (let index = 0; index < count; index++) {
      arr.push(value)
    }

    return arr
  }

  const arr1 = getArray(3, 'abc')
  console.log(arr1[1].length2) // 没提示(正确/错误)  声明的数组中的元素是any类型

  const arr2 = getArray(3, 123.12)
  console.log(arr2[0].toFixed2())

  /* 用了TS, 还不能有正确/错误的提示 => 不太好的效果 */

})();

(() => {
  // 定义多个泛型: 当有多个不确定的数据类型时
  function fn<K, V>(a: K, b: V): [K, V] {
    return [a, b]
  }

  const result = fn<string, number>('abc', 123)
})();